use axum::{extract::Query, Json};
use com::{ code, file::{create::{create_dir_all, create_file_write_all, open_file_append_write_all, open_file_clear_write_all, open_file_clear_write_all_not_null, open_file_read_to_str, open_file_read_to_str_, write_all_flie}, remove::remove_file, utils::{ exist, exist_err, exist_not_err, get_parent_path_str}}, query };
use sea_orm::query::*;
use serde_json::json;

pub async fn create_table(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let template = query::str(&body,"template")?;
    
    let folder = folder + "/migration/src/";
    let file =  table_name.to_owned() + ".rs";
    let path = folder.to_owned() + &file;
    let lib  = folder.to_owned() + "/lib.rs";
    _ = exist_not_err(&folder)?;
    _ = exist_not_err(&lib)?;
    _ = exist_err(&path)?;
    
    _ = create_file_write_all(&path, &template).await?;
    // 将文件写入 lib
    let mut buffer = open_file_read_to_str(&lib).await?;
    let s1 = "pub struct Migrator;";
    let s2 = "   ]";
    let c1 = format!("mod {};", table_name);

    if buffer.contains(&c1){
        return code::err(format!("表文件【{}】已存在于 lib.rs 中，不允许操作", &file))
    }
    if buffer.contains("\t\t]"){
        return code::err("结尾格式不正确")
    }

    let c2 = format!("Box::new({}::Migration),", table_name);

    buffer = buffer.replace(s1, &format!("{}\n{}", c1, s1));
    buffer = buffer.replace(s2, &format!("       {}\n     {}", c2, s2));
    
    open_file_clear_write_all(&lib, &buffer).await
}
pub async fn create_template(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let template = query::str(&body,"template")?;
    
    let folder_temp = folder.to_owned() + "/src/__temp/";
    let mod_path = folder_temp.to_owned() + "mod.rs";
    let path = folder_temp.to_owned() + &table_name;
    _ = exist_not_err(&folder)?;
    // _ = exist_err(&path)?;
    
    let _ = create_dir_all(&folder_temp).await?;
    let _ = create_dir_all(&path).await?;

    if !exist(&mod_path)?{
        _ = create_file_write_all(&mod_path, " ").await?;
    }

    let master_path = path.to_owned() + "/master.rs";
    _ = create_file_write_all(&master_path, &template).await?;

    if let Some(f) = query::str_op(&body,"union")? {
        let mod_path = path.to_owned() + "/mod.rs";
        _ = create_file_write_all(&mod_path, &f).await?;
    }
    code::ok()
}

pub async fn read_table(Query(param): Query<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&param,"table_name")?;
    let folder = query::str(&param,"folder")?;
    
    let table_folder = folder.to_owned() + "/migration/src/";
    let file_name =  table_name.to_owned() + ".rs";
    let table_path = table_folder.to_owned() + &file_name;
    let model_folder = folder.to_owned() + "/model/src/";
    let model_path = model_folder.to_owned() + &file_name;
    let mut obj = json!({});

    _ = exist_not_err(&table_folder)?;
    _ = exist_not_err(&model_folder)?;
    obj["table"] = json!(open_file_read_to_str_(&table_path).await?);
    obj["model"] = json!(open_file_read_to_str_(&model_path).await?);
    code::data(obj)
}
pub async fn save_table(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let template = query::str(&body,"table")?;
    
    let table_folder = folder.to_owned() + "/migration/src/";
    let file =  table_name.to_owned() + ".rs";
    let table_path = table_folder.to_owned() + &file;

    _ = exist_not_err(&table_folder)?;
    open_file_clear_write_all_not_null(&table_path, &template).await
}

pub async fn read_model(Query(param): Query<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&param,"table_name")?;
    let folder = query::str(&param,"folder")?;
    
    let entity_folder = get_parent_path_str(&folder)? + "/entity/";
    let model_folder = folder.to_owned() + "/model/src/";
    let file_name =  table_name.to_owned() + ".rs";
    let entity_path = entity_folder.to_owned() + &file_name;
    let model_path = model_folder.to_owned() + &file_name;
    let mut obj = json!({});

    _ = exist_not_err(&entity_folder)?;
    _ = exist_not_err(&model_folder)?;
    obj["entity"] = json!(open_file_read_to_str_(&entity_path).await?);
    obj["model"] = json!(open_file_read_to_str_(&model_path).await?);
    code::data(obj)
}
pub async fn save_model(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let template = query::str(&body,"model")?;
    
    let model_folder = folder.to_owned() + "/model/src/";
    let file_name =  table_name.to_owned() + ".rs";
    let model_path = model_folder.to_owned() + &file_name;
    
    _ = exist_not_err(&model_folder)?;
    
    _ = write_all_flie(&model_path, &template).await?;
    save_model_lib(&table_name, &folder).await
}

async fn save_model_lib(table_name:&str, folder:&str) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let folder = folder.to_owned() + "/model/src/";
    let path = folder.to_owned() + "lib.rs";
    let buffer = open_file_read_to_str(&path).await?;
    let s = format!("\npub mod {};", table_name);
	let p = format!("pub mod {};", table_name);
    if buffer.contains(&p) {
        // return code::err(format!("{} 已存在，无法写入", s))
        return code::ok()
    }
    open_file_append_write_all(&path, &s).await
}
// 移除相关文件
pub async fn remove(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let file_name =  table_name.to_owned() + ".rs";
    // 移除 table
    let table_folder = folder.to_owned() + "/migration/src/";
    let table_path = table_folder.to_owned() + &file_name;
    let table_lib_path  = table_folder.to_owned() + "/lib.rs";
    
    if exist(&table_path)? {
        let table_lib_str = open_file_read_to_str(&table_lib_path).await?;
        let s1 = format!("mod {};", table_name);
        let s2 = format!("Box::new({}::Migration),", table_name);
        let table_lib_str = table_lib_str.replace(&s1, "");
        let table_lib_str = table_lib_str.replace(&s2, "");
        _ = open_file_clear_write_all(&table_lib_path, &table_lib_str).await?;
        _ = remove_file(&table_path).await?;
    }

    // 移除 model
    let model_folder = folder.to_owned() + "/model/src/";
    let model_path = model_folder.to_owned() + &file_name;
    let model_lib_path  = model_folder.to_owned() + "/lib.rs";
    
    if exist(&model_path)?{
        let model_lib_str = open_file_read_to_str(&model_lib_path).await?;

        let s = format!("\npub mod {};", table_name);
        let model_lib_str = model_lib_str.replace(&s, "");
        _ = open_file_clear_write_all(&model_lib_path, &model_lib_str).await?;
        _ = remove_file(&model_path).await?;
    }
    code::ok()
}
// 生成前端模板
pub async fn save_front_temp(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let template = query::str(&body,"template")?;
    
    let model_folder = folder.to_owned() + "/src/__temp/";
    let file_name =  table_name.to_owned() + ".jsx";
    let model_path = model_folder.to_owned() + &file_name;
    
    _ = exist_not_err(&folder)?;
    _ = create_dir_all(&model_folder).await?;
    
    create_file_write_all(&model_path, &template).await
}
// 反向创建表
pub async fn save_sql_table(Json(body):Json<JsonValue>) -> Result<Json<JsonValue>, Json<JsonValue>>{
    let table_name = query::str(&body,"table_name")?;
    let folder = query::str(&body,"folder")?;
    let template = query::str(&body,"template")?;
    
    let folder = folder + "/migration/src/";
    let file =  table_name.to_owned() + ".rs";
    let path = folder.to_owned() + &file;
    let lib  = folder.to_owned() + "/lib.rs";
    _ = exist_not_err(&folder)?;
    _ = exist_not_err(&lib)?;

    if exist(&path)? {
        open_file_clear_write_all_not_null(&path, &template).await
    }else{
        _ = create_file_write_all(&path, &template).await?;
        // 将文件写入 lib
        let mut buffer = open_file_read_to_str(&lib).await?;
        let s1 = "pub struct Migrator;";
        let s2 = "   ]";
        let c1 = format!("mod {};", table_name);

        if buffer.contains(&c1){
            return code::err(format!("表文件【{}】已存在于 lib.rs 中，不允许操作", &file))
        }
        if buffer.contains("\t\t]"){
            return code::err("结尾格式不正确")
        }

        let c2 = format!("Box::new({}::Migration),", table_name);

        buffer = buffer.replace(s1, &format!("{}\n{}", c1, s1));
        buffer = buffer.replace(s2, &format!("       {}\n     {}", c2, s2));
        
        open_file_clear_write_all(&lib, &buffer).await
    }
}